/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.console;

import com.icee.myth.common.message.serverMessage.InternalChannelMessage;
import com.icee.myth.common.message.serverMessage.Message;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelUpstreamHandler;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;

/**
 *
 * @author liuxianke
 */
public class ConsoleToManagerClient {

    //Singleton
    private static ConsoleToManagerClient INSTANCE = new ConsoleToManagerClient();

    private String host; // Server的主机地址
    private int port; // Server的端口地址
    private ClientBootstrap bootstrap;
    private Channel managerChannel; // channelContext connect to server

    //getInstance操作的第一次调用在Main的start中，因此无需同步
    public static ConsoleToManagerClient getInstance() {
        return INSTANCE;
    }

    private ConsoleToManagerClient() {
    }

    public void init(String host, int port, LengthFieldBasedFrameDecoder lengthFieldBasedFrameDecoder,OneToOneEncoder customEncoder, ChannelUpstreamHandler targetHandler) {
        this.host = host;
        this.port = port;

        ChannelFactory factory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
        this.bootstrap = new ClientBootstrap(factory);

        // Set up the default event pipeline.
        ChannelPipeline p = bootstrap.getPipeline();
        p.addLast("frameDecoder", lengthFieldBasedFrameDecoder);
        p.addLast("customEncoder", customEncoder);

        p.addLast("handler", targetHandler);

        this.bootstrap.setOption("tcpNoDelay", true);
        this.bootstrap.setOption("keepAlive", true);
    }

    public void connectToServer() {
        // 连接服务
        // Start the connection attempt.
        MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_INFO, "Connecting to server...");
        bootstrap.connect(new InetSocketAddress(host, port));
    }

    public Channel getManagerChannel() {
        return managerChannel;
    }

    public void handleMessage(Message message) {
        switch (message.getType()) {
            case CONSOLE_MANAGER_CONNECT: {
                // 处理ManagerConnect消息
                assert (managerChannel == null);
                managerChannel = ((InternalChannelMessage)message).channel;

                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_INFO, "Manager connected!");
                break;
            }
            case CONSOLE_MANAGER_CLOSE: {
                // 处理ClusterClose消息
                managerChannel = null;
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_INFO, "Manager closed!");

                break;
            }
        }
    }
}
